import {
  HumanizeDurationLanguage,
  HumanizeDuration,
} from "humanize-duration-ts";

export interface DestinationUrl {
  url: string;
  type: 0 | 1 | 2 | 3;
  text?: string;
  time?: number;
}

export function getBaseUrl(url: string): string | undefined {
  const urlo = new URL(url);
  return /(.+\/).+$/.exec(urlo.origin + urlo.pathname)?.[1];
}

export function determineType(url: string, text: string): DestinationUrl {
  let type: 0 | 1 | 2 | 3 = 3;
  if (text.startsWith("#EXTM3U")) type = 0;
  if (text.indexOf("</Period>") > 0) type = 1;
  if (text.indexOf("</SmoothStreamingMedia>") > 0) type = 1;
  return {
    type,
    url,
    ...parseM3U8(text, getBaseUrl(url)),
  };
}

function toAbsUrl(url: string, base?: string) {
  return url.startsWith("http://") ||
    url.startsWith("https://") ||
    url.startsWith("data:")
    ? url
    : new URL(url, base).href;
}

export function parseM3U8(
  otext: string,
  base?: string,
): {
  text: string;
  time: number;
} {
  let time = 0;
  const text = otext
    .split("\n")
    .map((line) => {
      if (line.startsWith("#")) {
        const uri = /URI="(.+?)"/.exec(line);
        if (uri) {
          return line.replace(uri[0], `URI="${toAbsUrl(uri[1], base)}"`);
        } else {
          if (line.startsWith("#EXTINF:")) {
            const lineTime = Number.parseFloat(
              /^#EXTINF:\s*(-?\d+(?:\.\d+)?)\s*(?:,.*)?$/.exec(line)?.[1] ??
                "0",
            );
            if (lineTime > 0) time += lineTime;
          }
          return line;
        }
      } else if (line === "") {
        return line;
      } else {
        return toAbsUrl(line, base);
      }
    })
    .join("\n");
  return {
    text,
    time,
  };
}

export function createLuLuButton(
  text: string,
  color: "safe" | "warn" | "primary" | "error",
  click: () => void,
) {
  const button = document.createElement("button");
  button.setAttribute("is", "ui-button");
  button.setAttribute("type", color);
  button.setAttribute("size", "mini");
  button.textContent = text;
  button.addEventListener("click", click);
  return button;
}

export function filtUrls(orig: DestinationUrl[]): DestinationUrl[] {
  return [
    ...new Set(
      orig.filter(
        (vo) => vo.url.startsWith("http") && typeof vo.type == "number",
      ),
    ),
  ];
}

export function howLong(time: number | undefined): string {
  return time
    ? new HumanizeDuration(new HumanizeDurationLanguage()).humanize(
        time * 1000,
        {
          language: "zh_CN",
          units: ["h", "m", "s"],
          round: true,
          delimiter: " ",
        },
      )
    : "未知";
}
